﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Xml;
using System.Globalization;

namespace EvriConnector
{
    public struct Facet
    {
        public string count { get; set; }
        public string name { get; set; }
    }

    public struct Property
    {
        public string name { get; set; }
        public string value { get; set; }
    }

    public class Entity : IComparable
    {
        public Double score {get; set;}
        public string id { get; set; }
        public string href { get; set; }
        public string type { get; set; }
        public string name { get; set; }
        public Facet[] facets;
        public Property[] properties;

        public int CompareTo(object obj)
        {
            Entity ent = (Entity) obj;
            return ent.score.CompareTo(score);
        }
    }

    public class EntityParser
    {
        private Facet[] ParseFacets(XmlNode facetList)
        {
            Facet[] result = new Facet[facetList.ChildNodes.Count];
            Int32 index = 0;

            foreach (XmlNode facet in facetList)
            {
                Facet currentFacet = new Facet();
                XmlAttributeCollection attribs = facet.Attributes;
                currentFacet.count = attribs["count"].Value;
                currentFacet.name = facet["name"].ChildNodes[0].Value;

                result[index++] = currentFacet;
            }

            return result;
        }

        private Property[] ParseProperties(XmlNode propList)
        {
            Property[] result = new Property[propList.ChildNodes.Count];
            Int32 index = 0;

            foreach (XmlNode prop in propList)
            {
                Property currentProp = new Property();
                currentProp.name = prop["name"].ChildNodes[0].Value;
                currentProp.value = prop["value"].ChildNodes[0].Value;

                result[index++] = currentProp;
            }

            return result;
        }

        private Entity[] ParseEntities(XmlNode entityList)
        {
            Entity[] result = new Entity[entityList.ChildNodes.Count];
            Int32 index = 0;

            NumberFormatInfo provider = new NumberFormatInfo();

            provider.NumberDecimalSeparator = ",";
            provider.NumberGroupSeparator = ".";
            provider.NumberGroupSizes = new int[] { 3 };


            foreach(XmlNode entity in entityList)
            {
                XmlElement facetList = entity["facets"];
                XmlElement propList = entity["properties"];

                Entity currentEnt = new Entity();
                XmlAttributeCollection attribs = entity.Attributes;
                currentEnt.score = Convert.ToDouble(attribs["score"].Value, provider);
                currentEnt.id = attribs["id"].Value;
                currentEnt.href = attribs["href"].Value;
                currentEnt.type = entity["type"].ChildNodes[0].Value;
                currentEnt.name = entity["name"].ChildNodes[0].Value;
                
                currentEnt.facets = ParseFacets(facetList);
                currentEnt.properties = ParseProperties(propList);

                result[index++] = currentEnt;
            }

            return result;
        }

        //in - the entityList root node
        public Entity[] Process(XmlNodeList entityList)
        {
            //it contains only one tag - entityList
            Entity[] result = ParseEntities(entityList[0]);
            
            return result;
        }
    }
}
